///////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2009 Summit Contributors.  
// See: http://code.google.com/p/tyemill/wiki/SummitContributors
//
// The name and logo of Summit are trademarks of TYEMILL, LLC - All Rights 
// Reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a 
// copy of this software and associated documentation files (the "Software"), 
// to deal in the Software without restriction, including without 
// limitation the rights to use, copy, modify, merge, publish, distribute, 
// sublicense, and/or sell copies of the Software, and to permit persons to 
// whom the Software is furnished to do so, subject to the following 
// conditions:
//
// The above copyright notice and this permission notice shall be included 
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////////////////////////////////////////

package summit.net
{

import flash.net.URLRequest;
import flash.net.URLRequestHeader;

import mx.utils.Base64Encoder;

import summit.data.AccountToken;	

/** Represents a Basecamp API request to be issued to Basecamp via the 
 * <code>BasecampLoader</code>. **/
public class BasecampRequest
{
	/** @private Storage **/
	private var _apiURL:String
	private var _resource:String;
	private var _apiOperation:String;
	private var _requestMethod:String;
	private var _data:XML;
	private var _callback:Function;
	private var _xmlAdditions:Object; // if it is here - will add to data
	
	/** @private **/
	public var summitData:Object;
	
	/** Constructor.
	 * @param apiURL
	 * The portion of the URL specific to the API call.
	 * @param method
	 * The method used to communicated with the Basecamp API (e.g. POST).
	 * @param resource
	 * The resource the request was made on (e.g. Message).
	 * @param operation
	 * The operation requested on the specified resource.
	 * @param data
	 * The XML data to push to the Basecamp API.
	 */
	public function BasecampRequest(apiURL:String, urlRequestMethod:String,
	resource:String, apiOperation:String, data:XML = null)
	{
		_apiURL = apiURL;
		_requestMethod = urlRequestMethod;
		_resource = resource;
		_apiOperation = apiOperation;
		_data = data;
	}
	
	/** Elements that should be added to the Basecamp API's XML response. **/
	public function get xmlAdditions():Object
	{
		return _xmlAdditions; 
	}
	
	/** @private **/
	public function set xmlAdditions(value:Object):void
	{
		_xmlAdditions = value;
	}
	
	/** A function to call on successful completion of the API request. 
	 * The signature of the callback must be <code>function(APIEvent)</code>. 
	 ***/
	public function get callback():Function
	{
		return _callback; 
	}
	
	/** @private **/
	public function set callback(value:Function):void
	{
		_callback = value;
	}
	
	/** The operation requested on a specific Basecamp resource. **/
	public function get operation():String
	{
		return _apiOperation; 
	}
	
	/** @private **/
	public function set operation(value:String):void
	{
		_apiOperation = value;
	}
	
	/** The portion of the URL specific to the API resource and operation. **/
	public function get apiURL():String
	{
		return _apiURL;
	}
	
	/** @private **/
	public function set apiURL(value:String):void
	{
		_apiURL = value;
	}

	/** The XML data which is pushed to the Basecamp API. **/
	public function get data():XML
	{
		return _data;
	}
	
	/** @private **/
	public function set data(value:XML):void
	{
		_data = value;
	}
	
	/** The <code>URLRequestMethod</code> specific to this request. **/	
	public function get urlRequestMethod():String
	{
		return _requestMethod;
	}
	
	/** @private **/
	public function set urlRequestMethod(value:String):void
	{
		_requestMethod = value;
	}
	
	/** The resource this request is specific to. **/
	public function get resource():String
	{
		return _resource;
	}
	
	/** @private **/
	public function set resource(value:String):void
	{
		_resource = value;
	}
	
	/**
	 * Creates a URLRequest from the state of this BasecampRequest instance.
	 * 
	 * @param token An instance of a AccountToken representing Basecamp 
	 * account information.
	 * 
	 * @return URLRequest To be used with a standard URLLoader.
	 */
	public function toURLRequest(token:AccountToken):URLRequest
	{
		var request:URLRequest 		= new URLRequest(token.url + apiURL);
		request.contentType 		= "application/xml";
		request.method 				= _requestMethod;
		request.data				= data == null ? null : data.toXMLString();
		
		var headerRequests:Array 	= new Array(2);
		var encoder64:Base64Encoder = new Base64Encoder();
		encoder64.encode(token.user + ":" + token.password);
		
		var credentials:String 		= encoder64.toString();
		
		headerRequests[0] = new URLRequestHeader("accept", "application/xml");
		headerRequests[1] = new URLRequestHeader("Authorization", "Basic " + 
			credentials);
		
		request.requestHeaders = headerRequests;
		
		return request;			
	}
}
}
//////////////////////////////////////////////////////// gmarius@tyemill.com //